Absolute Routine ---------------------------------------------------------------------------- Action Transfers control to a machine-language procedure. Syntax CALL Absolute (- argumentlist,- integervariable%) Remarks The Absolute routine uses the following arguments. ----------------------------------------------------------------------------- Argument Description ---------------------------------------------------------------------------- argumentlist Arguments passed to a machine-language procedure as offsets (near pointers) from the current data segment. Although arguments are passed as offsets, the machine-language program is invoked with a far call. integervariable% The offset from the current code Argument Description ---------------------------------------------------------------------------- integervariable% The offset from the current code segment, set by DEF SEG, to the starting location of the procedure. The argument integervariable% is not passed to the procedure. Your program may need to execute a DEF SEG statement before executing Absolute to set the code segment for the called routine. Using a noninteger value for integervariable% produces unpredictable results. Note The Absolute routine is provided to maintain compatibility with earlier versions of BASIC. Mixed-language programming using the CALL and DECLARE statements provides a simpler way to use assembly language with BASIC. When using the Absolute routine in OS-2 protected mode, be careful not to refer to an illegal memory address. Before it executes the Absolute routine, BASIC attempts to get an executable-code-segment alias for the code you wish to access. If this operation fails, BASIC generates the error message Permission denied. A safe place to store user-written machine code is in memory allocated for a conventional BASIC object, such as an array. To use the Absolute routine in the QBX environment, use the QBX.QLB Quick library. To use the Absolute routine outside of the QBX environment, link your progra with the QBX.LIB file. The QBX.BI header file contains the necessary declarations for the Absolute routine. Basica Assembly-language programs that are invoked from BASICA and that have string arguments must be changed, because string descriptors are now 4 bytes long. For a near-string descriptor, the 4 bytes are the low byte and high byte of the string length, followed by the low byte and high byte of the string address. Far-string descriptors also are 4 bytes long, but their structure is proprietary. For more information on using far-string descriptors, see Chapter 12, "Mixed-Language Programming" and Chapter 13, "Mixed-Language Programming with Far Strings" in the Programmer's Guide. See Also CALL, CALLS Statements (Non-Basic) Example The following example uses Absolute to execute a machine-language program stored in an array. The program indicates whether a math coprocessor is installed. CONST nASMBYTES = 14 DEFINT A-Z DIM AsmProg(1 TO (nASMBYTES - 2)) ' The machine-language program stored as data to read into the array. AsmBytes. DATA &H55 . ' PUSH BPSave base pointer. DATA &H8B, &HEC. ' MOV BP,SP Get our own. DATA &HCD, &H11. ' INT 11HMake the ROM-BIOS call. DATA &H8B, &H5E, &H06. ' MOV BX,[BP+6]Get argument address. DATA &H89, &H07. ' MOV [BX],AXSave list in argument. DATA &H5D . ' POP BPRestore base pointer. DATA &HCA, &H02, &H00. ' RET 2Pop argument off stack 'and make far return. ' Poke the machine-language program into the array. P = VARPTR(AsmProg(1))' Get the starting offset of the array. DEF SEG = VARSEG(AsmProg(1)) ' Change the segment. FOR I = 0 TO nASMBYTES - 1 READ J POKE (P + I), J NEXT I ' Execute the program. The program expects a single integer argument. CALL Absolute(X%, VARPTR(AsmProg(1))) DEF SEG' Restore the segment. ' X% now contains bit-encoded equipment list returned by the system. ' Mask off all but the coprocessor bit (bit 2). CoProcessor = X% AND &H2 IF CoProcessor = 2 THEN PRINT "Math coprocessor present." ELSE PRINT "No math coprocessor." END IF